package com.sinry.api.aggregation.feign;

import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.json.JsonMapper;
import com.fasterxml.jackson.databind.type.TypeFactory;
import feign.FeignException;
import feign.Response;
import feign.Util;
import feign.codec.DecodeException;
import feign.codec.Decoder;
import org.springframework.http.HttpStatus;
import org.springframework.util.ObjectUtils;

import java.io.IOException;
import java.lang.reflect.Type;

/**
 * @author linxinlei
 * @project sinry-cloud
 * @description feign解码器
 * @date 2022/5/22
 **/
public class JsonResultDecoder<R> implements Decoder {

    @Override
    public Object decode(Response response, Type type) throws IOException, DecodeException, FeignException {
        if (ObjectUtils.isEmpty(response.body())) {
            throw new DecodeException(response.status(), "没有数据响应", response.request());
        }
        String bodyStr = Util.toString(response.body().asReader(Util.UTF_8));
        R res = this.json2obj(bodyStr, type);
        //如果返回错误，且为内部错误，则直接抛出异常
        if (response.status() != HttpStatus.OK.value()) {
            throw new DecodeException(response.status(), "接口返回错误：" + response.body(), response.request());
        }
        return res;
    }

    public <T> T json2obj(String jsonStr, Type targetType) {
        try {
            JsonMapper mapper = new JsonMapper();
            JavaType javaType = TypeFactory.defaultInstance().constructType(targetType);
            return mapper.readValue(jsonStr, javaType);
        } catch (IOException e) {
            throw new IllegalArgumentException("将JSON转换为对象时发生错误:" + jsonStr, e);
        }
    }
}
